/*
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhihu.matisse.library.provider;

import com.zhihu.matisse.library.MimeType;
import com.zhihu.matisse.library.ResourceTable;
import com.zhihu.matisse.library.component.CheckView;
import com.zhihu.matisse.library.model.*;
import com.zhihu.matisse.library.utils.TimeUtils;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.media.photokit.metadata.AVMetadataHelper;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.io.FileNotFoundException;
import java.util.ArrayList;

public class MediaProvider extends RecycleItemProvider {

    private ArrayList<Item> list;
    private Context mContext;
    private SelectedItemCollection mCollection;
    private SelectionSpec selectionSpec;
    private CheckStateListener mCheckStateListener;
    private OnMediaClickListener mOnMediaClickListener;

    public MediaProvider(Context context, ArrayList<Item> list, SelectedItemCollection collection) {
        selectionSpec = SelectionSpec.getInstance();
        this.list = list;
        mContext = context;
        mCollection = collection;
    }

    @Override
    public int getCount() {
        return list == null ? 0 : list.size();
    }

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

    @Override
    public long getItemId(int i) {
        return list == null ? 0 : list.get(i).hashCode();
    }

    public ArrayList<Item> getList() {
        return list;
    }

    @Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        Component v;
        if (component == null) {
            v = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_media_grid_layout, componentContainer, false);
        } else {
            v = component;
        }
        Image image = (Image) v.findComponentById(ResourceTable.Id_media_thumbnail);
        Text duration = (Text) v.findComponentById(ResourceTable.Id_media_duration);
        Image gif = (Image) v.findComponentById(ResourceTable.Id_media_gif);
        CheckView checkView = (CheckView) v.findComponentById(ResourceTable.Id_media_check);
        Text tvCamera = (Text) v.findComponentById(ResourceTable.Id_media_camera);
        Item item= (Item) getItem(i);
//        try {
//           item
//        }catch (Exception e){
//            e.printStackTrace();
//            item = new Item(Item.ITEM_ID_CAPTURE,"",0,"",0);
//        }
        if (item.id < 0){
            image.setVisibility(Component.HIDE);
            checkView.setVisibility(Component.HIDE);
            duration.setVisibility(Component.HIDE);
            gif.setVisibility(Component.HIDE);
            tvCamera.setVisibility(Component.VISIBLE);


        }else {
            image.setVisibility(Component.VISIBLE);
            checkView.setVisibility(Component.VISIBLE);
            tvCamera.setVisibility(Component.HIDE);
            checkView.setCountable(selectionSpec.countable);

            if (MimeType.isImage(item.mimeType)) {
                Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(item.id));
                selectionSpec.imageEngine.loadImage(mContext,0,0,image,uri);
                if (MimeType.isGif(item.mimeType)) {
                    gif.setVisibility(Component.VISIBLE);
                } else {
                    gif.setVisibility(Component.HIDE);
                }
                duration.setVisibility(Component.HIDE);
            } else if (MimeType.isVideo(item.mimeType)) {
                gif.setVisibility(Component.HIDE);
                duration.setVisibility(Component.VISIBLE);
                Uri uri = Uri.appendEncodedPathToUri(AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(item.id));
                AVMetadataHelper avMetadataHelper = new AVMetadataHelper();
                duration.setText(TimeUtils.formatElapsedTime(item.duration / 1000));
                try {
                    if (avMetadataHelper.setSource(DataAbilityHelper.creator(mContext).openFile(uri, "r"))){
                        image.setPixelMap(avMetadataHelper.fetchVideoPixelMapByTime(1));
                    }
                } catch (DataAbilityRemoteException | FileNotFoundException e) {
                    e.printStackTrace();
                }
                avMetadataHelper.release();
            }
            checkView.setClickedListener(component12 -> updateSelectedItem(item,mContext));
            setCheckStatus(item,checkView);
        }
        v.setClickedListener(component1 -> {
            if (item.isCapture()){
                if (mOnMediaClickListener != null) {
                    mOnMediaClickListener.onMediaClick(null, item, i);
                }
            }else {
                if (selectionSpec.showPreview){
                    if (mOnMediaClickListener != null) {
                        mOnMediaClickListener.onMediaClick(null, item, i);
                    }
                }else {
                    updateSelectedItem(item,mContext);
                }
            }

        });
        return v;
    }

    private void setCheckStatus(Item item,CheckView checkView){
        if (selectionSpec.countable){
            int checkNum = mCollection.checkedNumOf(item);
            if (checkNum > 0){
                checkView.setEnabled(true);
                checkView.setCheckedNum(checkNum);
            }else {
                if (mCollection.maxSelectableReached()){
                    checkView.setEnabled(false);
                    checkView.setCheckedNum(CheckView.UNCHECKED);
                }else {
                    checkView.setEnabled(true);
                    checkView.setCheckedNum(checkNum);
                }
            }
        }else {
            boolean selected = mCollection.isSelected(item);
            if (selected) {
                checkView.setEnabled(true);
                checkView.setChecked(true);
            } else {
                if (mCollection.maxSelectableReached()) {
                    checkView.setEnabled(false);
                    checkView.setChecked(false);
                } else {
                    checkView.setEnabled(true);
                    checkView.setChecked(false);
                }
            }
        }
    }
    private void updateSelectedItem(Item item,Context holder) {
        if (selectionSpec.countable) {
            int checkedNum = mCollection.checkedNumOf(item);
            if (checkedNum == CheckView.UNCHECKED) {
                if (assertAddSelection(holder, item)) {
                    mCollection.add(item);
                    notifyCheckStateChanged();
                }
            } else {
                mCollection.remove(item);
                notifyCheckStateChanged();
            }
        } else {
            if (mCollection.isSelected(item)) {
                mCollection.remove(item);
                notifyCheckStateChanged();
            } else {
                if (assertAddSelection(holder, item)) {
                    mCollection.add(item);
                    notifyCheckStateChanged();
                }
            }
        }
    }
    public void registerOnMediaClickListener(OnMediaClickListener listener) {
        mOnMediaClickListener = listener;
    }

    public void unregisterOnMediaClickListener() {
        mOnMediaClickListener = null;
    }
    public void registerCheckStateListener(CheckStateListener listener) {
        mCheckStateListener = listener;
    }

    public void unregisterCheckStateListener() {
        mCheckStateListener = null;
    }
    private void notifyCheckStateChanged() {
        notifyDataChanged();
        if (mCheckStateListener != null) {
            mCheckStateListener.onUpdate();
        }
    }
    private boolean assertAddSelection(Context context, Item item) {
        IncapableCause cause = mCollection.isAcceptable(item);
        IncapableCause.handleCause(context, cause);
        return cause == null;
    }
    public interface CheckStateListener {
        void onUpdate();
    }
    public interface OnMediaClickListener {
        void onMediaClick(Album album, Item item, int adapterPosition);
    }
}
